package app

import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"time"

	"gitee.com/tomatomeatman/golang-repository/bricks/model"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/data"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/system"
	"gitee.com/tomatomeatman/golang-repository/bricks/utils/function/url"

	"gitee.com/tomatomeatman/golang-repository/bricks/utils/gin"

	Log "github.com/cihub/seelog"
	gg "github.com/gin-gonic/gin"
)

var appGinServer *http.Server

type BrickApp struct{}

/**
 * 程序注册码校验
 * @param key 干扰密钥
 * @param isClose 验证失败时是否关闭程序
 * @return
 */
func (BrickApp) CheckPollCode(key string, isClose bool) bool {
	code := AppUtil{}.ReadConfigKey("App", "PollCode", "").(string)
	bl, _ := system.SystemUtil{}.CheckPollCode(code, key)
	if bl {
		return true
	}

	if isClose {
		fmt.Println("程序注册码校验失败，关闭程序")
		Log.Error("程序注册码校验失败，关闭程序")
		os.Exit(0)
	}

	fmt.Println("程序注册码校验失败")
	Log.Error("程序注册码校验失败")

	return false
}

/**
 * 程序运行
 * @param InterceptorFunc 拦截函数
 */
func (ba BrickApp) Run(InterceptorFunc func(ctx *gg.Context) bool) {
	Root := AppUtil{}.ReadConfigKey("System", "Root", "/webroot/").(string)
	Port := AppUtil{}.ReadConfigKey("System", "Port", "8080").(string)
	Title := AppUtil{}.ReadConfigKey("System", "Title", "").(string)
	Name := AppUtil{}.ReadConfigKey("System", "Name", "").(string)
	GinMode := AppUtil{}.ReadConfigKey("System", "Gin", "Release").(string)

	//DbNamedRules = AppUtil{}.ReadConfigKey("DataSource", "DbNamedRules", "common").(string) //common 通用数据库命名格式定义;bricks 自定义的格式

	go Cloud{}.RegistraCloud() //注册服务到注册中心

	r := gin.GetGin(GinMode, Root, InterceptorFunc, ba.Shutdown)
	// HttpHandleInfos := gin.GinUtil{}.GetController()

	// switch strings.ToUpper(GinMode) { //gin运行模式
	// case "RELEASE":
	// 	gin.SetMode(gin.ReleaseMode)
	// 	break
	// case "TEST":
	// 	gin.SetMode(gin.TestMode)
	// 	break
	// case "DEBUG":
	// 	gin.SetMode(gin.DebugMode)
	// 	break
	// default:
	// 	gin.SetMode(gin.ReleaseMode)
	// }

	// r := gin.Default()

	// gin.GinUtil{}.SetCors(r)             //设置跨域
	// gin.GinUtil{}.SetStatic(r, "."+Root) //设置静态目录

	// r.GET("/shutdown", ba.Shutdown)
	// r.POST("/shutdown", ba.Shutdown)

	// for _, val := range HttpHandleInfos {
	// 	switch val.Type {
	// 	case GET:
	// 		r.GET(val.Url, gin.GinUtil{}.GetHandleFunc(val.Url, GET, InterceptorFunc, HttpHandleInfos))
	// 		break
	// 	case POST:
	// 		r.POST(val.Url, gin.GinUtil{}.GetHandleFunc(val.Url, POST, InterceptorFunc, HttpHandleInfos))
	// 		break
	// 	case DELETE:
	// 		r.DELETE(val.Url, gin.GinUtil{}.GetHandleFunc(val.Url, DELETE, InterceptorFunc, HttpHandleInfos))
	// 		break
	// 	case PUT:
	// 		r.PUT(val.Url, gin.GinUtil{}.GetHandleFunc(val.Url, PUT, InterceptorFunc, HttpHandleInfos))
	// 		break
	// 	case OPTIONS:
	// 		r.OPTIONS(val.Url, gin.GinUtil{}.GetHandleFunc(val.Url, OPTIONS, InterceptorFunc, HttpHandleInfos))
	// 		break
	// 	default:
	// 		r.GET(val.Url, func(ctx *gin.Context) {
	// 			ctx.JSONP(http.StatusBadRequest, model.MsgEmity{}.Err(1001, "请求方式错误,不支持此方式"))
	// 		})
	// 	}
	// }

	fmt.Println(data.StringUtil{}.Append("================ ", Title, Name, "启动完毕,使用端口:", Port, ",时间:", time.Now().Format("2006-01-02 15:04:05"), " ================"))

	// r.Run(":" + Port) // 监听并在 0.0.0.0:8080 上启动服务

	//-- 优雅进行关闭系统 --//

	appGinServer = &http.Server{
		Addr:    ":" + Port,
		Handler: r,
	}

	if err := appGinServer.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
		Log.Error("启动服务发生异常: ", err)
	}
}

// 关闭服务
func (ba BrickApp) Shutdown(ctx *gg.Context) {
	key := url.UrlUtil{}.GetParam(ctx, "sInsideKey", "").(string)
	if "" == key {
		ctx.JSONP(http.StatusOK, model.MsgEmity{}.Err(100001, "请求密钥参数sInsideKey缺失"))
		return
	}

	appKey := AppUtil{}.ReadConfigKey("App", "InsideKey", "12345").(string)
	if appKey != key {
		ctx.JSONP(http.StatusOK, model.MsgEmity{}.Err(100001, "请求密钥参数错误"))
		return
	}

	Log.Debug("关闭服务...")

	if err := appGinServer.Shutdown(ctx); err != nil {
		Log.Debug("服务强制关闭发生异常:", err)
		ctx.JSONP(http.StatusOK, model.MsgEmity{}.Err(100003, "服务强制关闭发生异常"))
		return
	}

	fmt.Println("服务关闭")
	ctx.JSONP(http.StatusOK, model.MsgEmity{}.Success(9999, "服务强制关闭成功"))
}
